{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "8ec84471-d494-4e98-a301-74abc0547f79",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import numpy as np\n",
    "from scipy.signal import butter, filtfilt\n",
    "import networkx as nx\n",
    "from scipy.ndimage import zoom\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "def load_and_validate_data(file_path):\n",
    "    \"\"\"\n",
    "    Load data from a file and validate its presence.\n",
    "    Return None if data is invalid or shapes are inconsistent.\n",
    "    \"\"\"\n",
    "    try:\n",
    "        loaded_data = np.load(file_path)\n",
    "        \n",
    "        \n",
    "        ppg_f = loaded_data.get('ppg_f')\n",
    "        ecg_f = loaded_data.get('ecg_f')\n",
    "        seg_dbp = loaded_data.get('seg_dbp')\n",
    "        seg_sbp = loaded_data.get('seg_sbp')\n",
    "        \n",
    "        \n",
    "        if ppg_f is None or ecg_f is None or seg_dbp is None or seg_sbp is None:\n",
    "            return None\n",
    "        \n",
    "       \n",
    "        if ppg_f.size == 0 or ecg_f.size == 0 or seg_dbp.size == 0 or seg_sbp.size == 0:\n",
    "            return None\n",
    "\n",
    "        return ppg_f, ecg_f, seg_dbp, seg_sbp\n",
    "    \n",
    "    except Exception as e:\n",
    "        print(f\"Error loading {file_path}: {e}\")\n",
    "        return None\n",
    "\n",
    "def bandpass_filter(data, lowcut, highcut, fs, order=5):\n",
    "    \"\"\"\n",
    "    Apply a bandpass filter to the data.\n",
    "    \"\"\"\n",
    "    nyquist = 0.5 * fs\n",
    "    low = lowcut / nyquist\n",
    "    high = highcut / nyquist\n",
    "    b, a = butter(order, [low, high], btype='band')\n",
    "    return filtfilt(b, a, data)\n",
    "\n",
    "def preprocess_signal(signal, fs):\n",
    "    \"\"\"\n",
    "    Preprocess the signal by bandpass filtering and normalization.\n",
    "    \"\"\"\n",
    "    filtered_signal = bandpass_filter(signal, 0.5, 40, fs)\n",
    "    normalized_signal = (filtered_signal - np.mean(filtered_signal)) / np.std(filtered_signal)\n",
    "    return normalized_signal\n",
    "    \n",
    "def combine_data_from_folder(folder_path , batch_size=100):\n",
    "    \"\"\"\n",
    "    Combine and preprocess data from all valid files in the folder and generate VG images.\n",
    "    \"\"\"\n",
    "    combined_ppg = []\n",
    "    combined_ecg = []\n",
    "    combined_seg_dbp = []\n",
    "    combined_seg_sbp = []\n",
    "\n",
    "    for file_name in os.listdir(folder_path):\n",
    "        file_path = os.path.join(folder_path, file_name)\n",
    "        \n",
    "        if not file_path.endswith('.npz'):\n",
    "            continue\n",
    "        \n",
    "        data = load_and_validate_data(file_path)\n",
    "        \n",
    "        if data is None:\n",
    "            print(f\"Skipping invalid file: {file_path}\")\n",
    "            continue\n",
    "        \n",
    "        ppg_f, ecg_f, seg_dbp, seg_sbp = data\n",
    "        \n",
    "        if ppg_f.ndim == 3:\n",
    "            for i in range(ppg_f.shape[0]):\n",
    "                preprocessed_ppg = preprocess_signal(ppg_f[i], 1000)\n",
    "                combined_ppg.append(preprocessed_ppg)\n",
    "        else:\n",
    "            print(f\"Skipping PPG data with unexpected shape: {ppg_f.shape}\")\n",
    "        \n",
    "        if ecg_f.ndim == 3:\n",
    "            for i in range(ecg_f.shape[0]):\n",
    "                preprocessed_ecg = preprocess_signal(ecg_f[i], 1000)\n",
    "                combined_ecg.append(preprocessed_ecg)\n",
    "        else:\n",
    "            print(f\"Skipping ECG data with unexpected shape: {ecg_f.shape}\")\n",
    "        \n",
    "        if seg_dbp.ndim == 2:\n",
    "            combined_seg_dbp.append(seg_dbp)\n",
    "        else:\n",
    "            print(f\"Skipping SegDBP data with unexpected shape: {seg_dbp.shape}\")\n",
    "        \n",
    "        if seg_sbp.ndim == 2:\n",
    "            combined_seg_sbp.append(seg_sbp)\n",
    "        else:\n",
    "            print(f\"Skipping SegSBP data with unexpected shape: {seg_sbp.shape}\")\n",
    "        \n",
    "        if len(combined_ppg) >= batch_size:\n",
    "            combined_ppg = np.stack(combined_ppg, axis=0)\n",
    "            combined_ecg = np.stack(combined_ecg, axis=0)\n",
    "            combined_seg_dbp = np.concatenate(combined_seg_dbp, axis=0)\n",
    "            combined_seg_sbp = np.concatenate(combined_seg_sbp, axis=0)\n",
    "            \n",
    "            yield combined_ppg, combined_ecg, combined_seg_dbp, combined_seg_sbp\n",
    "            combined_ppg = []\n",
    "            combined_ecg = []\n",
    "            combined_seg_dbp = []\n",
    "            combined_seg_sbp = []\n",
    "            \n",
    "\n",
    "    if combined_ppg:\n",
    "        combined_ppg = np.stack(combined_ppg, axis=0)\n",
    "    else:\n",
    "        combined_ppg = np.array([])\n",
    "        \n",
    "    if combined_ecg:\n",
    "        combined_ecg = np.stack(combined_ecg, axis=0)\n",
    "    else:\n",
    "        combined_ecg = np.array([])\n",
    "        \n",
    "    if combined_seg_dbp:\n",
    "        combined_seg_dbp = np.concatenate(combined_seg_dbp, axis=0)\n",
    "    else:\n",
    "        combined_seg_dbp = np.array([])\n",
    "        \n",
    "    if combined_seg_sbp:\n",
    "        combined_seg_sbp = np.concatenate(combined_seg_sbp, axis=0)\n",
    "    else:\n",
    "        combined_seg_sbp = np.array([])\n",
    "\n",
    "    yield combined_ppg, combined_ecg, combined_seg_dbp, combined_seg_sbp\n",
    "            \n",
    "\n",
    "\n",
    "train_dir = 'C:\\\\Users\\\\nihal\\\\Desktop\\\\NIHAL_IMP_DOCS\\\\Internship_PPG\\\\Train_data'\n",
    "val_dir = 'C:\\\\Users\\\\nihal\\\\Desktop\\\\NIHAL_IMP_DOCS\\\\Internship_PPG\\\\Validation_data'\n",
    "test_dir = 'C:\\\\Users\\\\nihal\\\\Desktop\\\\NIHAL_IMP_DOCS\\\\Internship_PPG\\\\Test_data'\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "f17ade90-1045-4384-8369-69c366a52d1d",
   "metadata": {},
   "outputs": [],
   "source": [
    "val_data_generator = combine_data_from_folder(test_dir, batch_size=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "e88fd63f-5705-4d73-aeb5-ce28d4662982",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from skimage.transform import resize\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "def generate_poincare_matrix(time_series, matrix_size=(224, 224), bins=224):\n",
    "    x = time_series[:-1]\n",
    "    y = time_series[1:]\n",
    "    \n",
    "    # Generate a 2D histogram (density plot) to represent the Poincaré plot as a matrix\n",
    "    H, xedges, yedges = np.histogram2d(x, y, bins=bins, range=[[np.min(time_series), np.max(time_series)], [np.min(time_series), np.max(time_series)]])\n",
    "    \n",
    "    #Normalize the matrix values (optional)\n",
    "    #H = H / np.max(H)  # Normalize to values between 0 and 1\n",
    "    \n",
    "    # Resize the matrix to the desired size (if necessary)\n",
    "    if matrix_size != (bins, bins):\n",
    "        H_resized = np.resize(H, matrix_size)\n",
    "    else:\n",
    "        H_resized = H\n",
    "    \n",
    "    return H_resized"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "4ba4b76b-c1d2-4ea3-9b3e-9436a985edde",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Processing Batch 1...\n",
      "916\n",
      "Batch 1 processing complete.\n",
      "Processing Batch 2...\n",
      "492\n",
      "Batch 2 processing complete.\n",
      "Processing Batch 3...\n",
      "120\n",
      "Batch 3 processing complete.\n",
      "Processing Batch 4...\n",
      "1003\n",
      "Batch 4 processing complete.\n",
      "Processing Batch 5...\n",
      "454\n",
      "Batch 5 processing complete.\n",
      "Processing Batch 6...\n",
      "135\n",
      "Batch 6 processing complete.\n",
      "Processing Batch 7...\n",
      "522\n",
      "Batch 7 processing complete.\n",
      "Processing Batch 8...\n",
      "549\n",
      "Batch 8 processing complete.\n",
      "Processing Batch 9...\n",
      "993\n",
      "Batch 9 processing complete.\n",
      "Processing Batch 10...\n",
      "434\n",
      "Batch 10 processing complete.\n",
      "Processing Batch 11...\n",
      "525\n",
      "Batch 11 processing complete.\n",
      "Processing Batch 12...\n",
      "1291\n",
      "Batch 12 processing complete.\n",
      "Processing Batch 13...\n",
      "537\n",
      "Batch 13 processing complete.\n",
      "Processing Batch 14...\n",
      "308\n",
      "Batch 14 processing complete.\n",
      "Processing Batch 15...\n",
      "918\n",
      "Batch 15 processing complete.\n",
      "Processing Batch 16...\n",
      "378\n",
      "Batch 16 processing complete.\n",
      "Processing Batch 17...\n",
      "437\n",
      "Batch 17 processing complete.\n",
      "Processing Batch 18...\n",
      "831\n",
      "Batch 18 processing complete.\n",
      "Processing Batch 19...\n",
      "178\n",
      "Batch 19 processing complete.\n",
      "Processing Batch 20...\n",
      "488\n",
      "Batch 20 processing complete.\n",
      "Processing Batch 21...\n",
      "143\n",
      "Batch 21 processing complete.\n",
      "Processing Batch 22...\n",
      "211\n",
      "Batch 22 processing complete.\n",
      "Processing Batch 23...\n",
      "927\n",
      "Batch 23 processing complete.\n",
      "Processing Batch 24...\n",
      "495\n",
      "Batch 24 processing complete.\n",
      "Processing Batch 25...\n",
      "843\n"
     ]
    },
    {
     "ename": "KeyboardInterrupt",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[4], line 17\u001b[0m\n\u001b[0;32m     15\u001b[0m poi_all_fullpeaks \u001b[38;5;241m=\u001b[39m []\n\u001b[0;32m     16\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m ppg \u001b[38;5;129;01min\u001b[39;00m combined_ppg_batch:\n\u001b[1;32m---> 17\u001b[0m     poi_matrix\u001b[38;5;241m=\u001b[39m\u001b[43mgenerate_poincare_matrix\u001b[49m\u001b[43m(\u001b[49m\u001b[43mppg\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mflatten\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m     18\u001b[0m     poi_all_fullpeaks\u001b[38;5;241m.\u001b[39mappend(np\u001b[38;5;241m.\u001b[39marray(poi_matrix))\n\u001b[0;32m     20\u001b[0m poi_all_fullpeaks \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39marray(poi_all_fullpeaks)\n",
      "Cell \u001b[1;32mIn[3], line 10\u001b[0m, in \u001b[0;36mgenerate_poincare_matrix\u001b[1;34m(time_series, matrix_size, bins)\u001b[0m\n\u001b[0;32m      7\u001b[0m y \u001b[38;5;241m=\u001b[39m time_series[\u001b[38;5;241m1\u001b[39m:]\n\u001b[0;32m      9\u001b[0m \u001b[38;5;66;03m# Generate a 2D histogram (density plot) to represent the Poincaré plot as a matrix\u001b[39;00m\n\u001b[1;32m---> 10\u001b[0m H, xedges, yedges \u001b[38;5;241m=\u001b[39m \u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mhistogram2d\u001b[49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43my\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mbins\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mbins\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mrange\u001b[39;49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m[\u001b[49m\u001b[43m[\u001b[49m\u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmin\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtime_series\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmax\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtime_series\u001b[49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmin\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtime_series\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmax\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtime_series\u001b[49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m     12\u001b[0m \u001b[38;5;66;03m#Normalize the matrix values (optional)\u001b[39;00m\n\u001b[0;32m     13\u001b[0m \u001b[38;5;66;03m#H = H / np.max(H)  # Normalize to values between 0 and 1\u001b[39;00m\n\u001b[0;32m     14\u001b[0m \n\u001b[0;32m     15\u001b[0m \u001b[38;5;66;03m# Resize the matrix to the desired size (if necessary)\u001b[39;00m\n\u001b[0;32m     16\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m matrix_size \u001b[38;5;241m!=\u001b[39m (bins, bins):\n",
      "File \u001b[1;32m<__array_function__ internals>:200\u001b[0m, in \u001b[0;36mhistogram2d\u001b[1;34m(*args, **kwargs)\u001b[0m\n",
      "File \u001b[1;32m~\\anaconda3\\envs\\intern\\lib\\site-packages\\numpy\\lib\\twodim_base.py:820\u001b[0m, in \u001b[0;36mhistogram2d\u001b[1;34m(x, y, bins, range, density, weights)\u001b[0m\n\u001b[0;32m    818\u001b[0m     xedges \u001b[38;5;241m=\u001b[39m yedges \u001b[38;5;241m=\u001b[39m asarray(bins)\n\u001b[0;32m    819\u001b[0m     bins \u001b[38;5;241m=\u001b[39m [xedges, yedges]\n\u001b[1;32m--> 820\u001b[0m hist, edges \u001b[38;5;241m=\u001b[39m \u001b[43mhistogramdd\u001b[49m\u001b[43m(\u001b[49m\u001b[43m[\u001b[49m\u001b[43mx\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43my\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mbins\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mrange\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdensity\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mweights\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m    821\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m hist, edges[\u001b[38;5;241m0\u001b[39m], edges[\u001b[38;5;241m1\u001b[39m]\n",
      "File \u001b[1;32m<__array_function__ internals>:200\u001b[0m, in \u001b[0;36mhistogramdd\u001b[1;34m(*args, **kwargs)\u001b[0m\n",
      "File \u001b[1;32m~\\anaconda3\\envs\\intern\\lib\\site-packages\\numpy\\lib\\histograms.py:1010\u001b[0m, in \u001b[0;36mhistogramdd\u001b[1;34m(sample, bins, range, density, weights)\u001b[0m\n\u001b[0;32m   1005\u001b[0m     \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m   1006\u001b[0m         \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\n\u001b[0;32m   1007\u001b[0m         \t\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m`bins[\u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m]` must be an integer, when a scalar\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;241m.\u001b[39mformat(i)\n\u001b[0;32m   1008\u001b[0m         ) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01me\u001b[39;00m\n\u001b[1;32m-> 1010\u001b[0m     edges[i] \u001b[38;5;241m=\u001b[39m \u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mlinspace\u001b[49m\u001b[43m(\u001b[49m\u001b[43msmin\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msmax\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mn\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m   1011\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m np\u001b[38;5;241m.\u001b[39mndim(bins[i]) \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m1\u001b[39m:\n\u001b[0;32m   1012\u001b[0m     edges[i] \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39masarray(bins[i])\n",
      "File \u001b[1;32m<__array_function__ internals>:200\u001b[0m, in \u001b[0;36mlinspace\u001b[1;34m(*args, **kwargs)\u001b[0m\n",
      "File \u001b[1;32m~\\anaconda3\\envs\\intern\\lib\\site-packages\\numpy\\core\\function_base.py:139\u001b[0m, in \u001b[0;36mlinspace\u001b[1;34m(start, stop, num, endpoint, retstep, dtype, axis)\u001b[0m\n\u001b[0;32m    136\u001b[0m     integer_dtype \u001b[38;5;241m=\u001b[39m _nx\u001b[38;5;241m.\u001b[39missubdtype(dtype, _nx\u001b[38;5;241m.\u001b[39minteger)\n\u001b[0;32m    138\u001b[0m delta \u001b[38;5;241m=\u001b[39m stop \u001b[38;5;241m-\u001b[39m start\n\u001b[1;32m--> 139\u001b[0m y \u001b[38;5;241m=\u001b[39m \u001b[43m_nx\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43marange\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnum\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdtype\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdt\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241m.\u001b[39mreshape((\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m,) \u001b[38;5;241m+\u001b[39m (\u001b[38;5;241m1\u001b[39m,) \u001b[38;5;241m*\u001b[39m ndim(delta))\n\u001b[0;32m    140\u001b[0m \u001b[38;5;66;03m# In-place multiplication y *= delta/div is faster, but prevents the multiplicant\u001b[39;00m\n\u001b[0;32m    141\u001b[0m \u001b[38;5;66;03m# from overriding what class is produced, and thus prevents, e.g. use of Quantities,\u001b[39;00m\n\u001b[0;32m    142\u001b[0m \u001b[38;5;66;03m# see gh-7142. Hence, we multiply in place only for standard scalar types.\u001b[39;00m\n\u001b[0;32m    143\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m div \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m0\u001b[39m:\n",
      "\u001b[1;31mKeyboardInterrupt\u001b[0m: "
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import os\n",
    "\n",
    "output_dir = 'poincare_images_filt_batches'\n",
    "os.makedirs(output_dir, exist_ok=True)\n",
    "\n",
    "for batch_idx, (combined_ppg_batch, combined_ecg_batch, combined_seg_dbp_batch, combined_seg_sbp_batch) in enumerate(val_data_generator):\n",
    "   \n",
    "    output_file = os.path.join(output_dir, f'filt_poi_batch_{batch_idx + 1}.npz')\n",
    "    if os.path.exists(output_file):\n",
    "        print(f\"Batch {batch_idx + 1} already processed. Skipping...\")\n",
    "        continue\n",
    "    print(f\"Processing Batch {batch_idx + 1}...\")\n",
    "    print(len(combined_seg_dbp_batch))\n",
    "    poi_all_fullpeaks = []\n",
    "    for ppg in combined_ppg_batch:\n",
    "        poi_matrix=generate_poincare_matrix(ppg.flatten())\n",
    "        poi_all_fullpeaks.append(np.array(poi_matrix))\n",
    "    \n",
    "    poi_all_fullpeaks = np.array(poi_all_fullpeaks)\n",
    "    \n",
    "    batch_filename = os.path.join(output_dir, f'filt_poi_batch_{batch_idx + 1}.npz')\n",
    "    np.savez_compressed(batch_filename, poi_images=poi_all_fullpeaks)\n",
    "    \n",
    "    print(f\"Batch {batch_idx + 1} processing complete.\")\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "e50a6099-4386-457d-a54c-6e66015baae3",
   "metadata": {},
   "outputs": [],
   "source": [
    "def load_poi_images(folder_path, batch_idx):\n",
    "    poi_images_path = os.path.join(folder_path, f'filt_poi_batch_{batch_idx}.npz')\n",
    "    \n",
    "    if not os.path.exists(poi_images_path):\n",
    "        print(f\"poi image files do not exist for Batch {batch_idx}.\")\n",
    "        return None\n",
    "    \n",
    "    poi_images = np.load(poi_images_path)['poi_images']\n",
    "    \n",
    "    return poi_images\n",
    "\n",
    "folder_path = r'C:\\Users\\nihal\\Desktop\\poincare_images_filt_batches'\n",
    "\n",
    "def plot_poincare_matrix(poincare_matrix):\n",
    "    plt.figure(figsize=(6, 6))\n",
    "    plt.imshow(poincare_matrix, cmap='hot', origin='lower')  # You can change the colormap\n",
    "    plt.colorbar()  # Add color bar to show the value scale\n",
    "    plt.title(\"Poincaré Plot Matrix\")\n",
    "    plt.xlabel(\"x[i] (current point)\")\n",
    "    plt.ylabel(\"x[i+1] (next point)\")\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "eca59f44-a5e1-4221-b043-a8ca9709650e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Processing Batch 1...\n",
      "Batch 1 processing complete.\n",
      "Processing Batch 2...\n",
      "Batch 2 processing complete.\n",
      "Processing Batch 3...\n",
      "Batch 3 processing complete.\n",
      "Processing Batch 4...\n",
      "Batch 4 processing complete.\n",
      "Processing Batch 5...\n"
     ]
    },
    {
     "ename": "MemoryError",
     "evalue": "Unable to allocate 174. MiB for an array with shape (22779904,) and data type float64",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mMemoryError\u001b[0m                               Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[5], line 11\u001b[0m\n\u001b[0;32m      6\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m batch_idx, (combined_ppg_batch, combined_ecg_batch, combined_seg_dbp_batch, combined_seg_sbp_batch) \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(val_data_generator):\n\u001b[0;32m      7\u001b[0m    \n\u001b[0;32m      8\u001b[0m     \u001b[38;5;66;03m#if batch_idx + 1>4 :\u001b[39;00m\n\u001b[0;32m      9\u001b[0m         \u001b[38;5;66;03m#break\u001b[39;00m\n\u001b[0;32m     10\u001b[0m     \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mProcessing Batch \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mbatch_idx\u001b[38;5;250m \u001b[39m\u001b[38;5;241m+\u001b[39m\u001b[38;5;250m \u001b[39m\u001b[38;5;241m1\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m...\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m---> 11\u001b[0m     poi_images \u001b[38;5;241m=\u001b[39m \u001b[43mload_poi_images\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfolder_path\u001b[49m\u001b[43m,\u001b[49m\u001b[43mbatch_idx\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m     12\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m poi_images \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m     13\u001b[0m         \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mNo poincare images found for Batch \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mbatch_idx\u001b[38;5;250m \u001b[39m\u001b[38;5;241m+\u001b[39m\u001b[38;5;250m \u001b[39m\u001b[38;5;241m1\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m. Stopping...\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
      "Cell \u001b[1;32mIn[4], line 8\u001b[0m, in \u001b[0;36mload_poi_images\u001b[1;34m(folder_path, batch_idx)\u001b[0m\n\u001b[0;32m      5\u001b[0m     \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mpoi image files do not exist for Batch \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mbatch_idx\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m      6\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m----> 8\u001b[0m poi_images \u001b[38;5;241m=\u001b[39m \u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mload\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpoi_images_path\u001b[49m\u001b[43m)\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mpoi_images\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m]\u001b[49m\n\u001b[0;32m     10\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m poi_images\n",
      "File \u001b[1;32m~\\anaconda3\\envs\\intern\\lib\\site-packages\\numpy\\lib\\npyio.py:253\u001b[0m, in \u001b[0;36mNpzFile.__getitem__\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m    251\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m magic \u001b[38;5;241m==\u001b[39m \u001b[38;5;28mformat\u001b[39m\u001b[38;5;241m.\u001b[39mMAGIC_PREFIX:\n\u001b[0;32m    252\u001b[0m     \u001b[38;5;28mbytes\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mzip\u001b[38;5;241m.\u001b[39mopen(key)\n\u001b[1;32m--> 253\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mformat\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mread_array\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mbytes\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m    254\u001b[0m \u001b[43m                             \u001b[49m\u001b[43mallow_pickle\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mallow_pickle\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    255\u001b[0m \u001b[43m                             \u001b[49m\u001b[43mpickle_kwargs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpickle_kwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    256\u001b[0m \u001b[43m                             \u001b[49m\u001b[43mmax_header_size\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmax_header_size\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m    257\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m    258\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mzip\u001b[38;5;241m.\u001b[39mread(key)\n",
      "File \u001b[1;32m~\\anaconda3\\envs\\intern\\lib\\site-packages\\numpy\\lib\\format.py:814\u001b[0m, in \u001b[0;36mread_array\u001b[1;34m(fp, allow_pickle, pickle_kwargs, max_header_size)\u001b[0m\n\u001b[0;32m    801\u001b[0m     array \u001b[38;5;241m=\u001b[39m numpy\u001b[38;5;241m.\u001b[39mfromfile(fp, dtype\u001b[38;5;241m=\u001b[39mdtype, count\u001b[38;5;241m=\u001b[39mcount)\n\u001b[0;32m    802\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m    803\u001b[0m     \u001b[38;5;66;03m# This is not a real file. We have to read it the\u001b[39;00m\n\u001b[0;32m    804\u001b[0m     \u001b[38;5;66;03m# memory-intensive way.\u001b[39;00m\n\u001b[1;32m   (...)\u001b[0m\n\u001b[0;32m    812\u001b[0m     \u001b[38;5;66;03m# not correctly instantiate zero-width string dtypes; see\u001b[39;00m\n\u001b[0;32m    813\u001b[0m     \u001b[38;5;66;03m# https://github.com/numpy/numpy/pull/6430\u001b[39;00m\n\u001b[1;32m--> 814\u001b[0m     array \u001b[38;5;241m=\u001b[39m \u001b[43mnumpy\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mndarray\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcount\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdtype\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdtype\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m    816\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m dtype\u001b[38;5;241m.\u001b[39mitemsize \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[0;32m    817\u001b[0m         \u001b[38;5;66;03m# If dtype.itemsize == 0 then there's nothing more to read\u001b[39;00m\n\u001b[0;32m    818\u001b[0m         max_read_count \u001b[38;5;241m=\u001b[39m BUFFER_SIZE \u001b[38;5;241m/\u001b[39m\u001b[38;5;241m/\u001b[39m \u001b[38;5;28mmin\u001b[39m(BUFFER_SIZE, dtype\u001b[38;5;241m.\u001b[39mitemsize)\n",
      "\u001b[1;31mMemoryError\u001b[0m: Unable to allocate 174. MiB for an array with shape (22779904,) and data type float64"
     ]
    }
   ],
   "source": [
    "\n",
    "all_poi_images = []\n",
    "all_sbp_values = []\n",
    "all_dbp_values = []\n",
    "\n",
    "\n",
    "for batch_idx, (combined_ppg_batch, combined_ecg_batch, combined_seg_dbp_batch, combined_seg_sbp_batch) in enumerate(val_data_generator):\n",
    "   \n",
    "    #if batch_idx + 1>4 :\n",
    "        #break\n",
    "    print(f\"Processing Batch {batch_idx + 1}...\")\n",
    "    poi_images = load_poi_images(folder_path,batch_idx + 1)\n",
    "    if poi_images is None:\n",
    "        print(f\"No poincare images found for Batch {batch_idx + 1}. Stopping...\")\n",
    "        break\n",
    "    \n",
    "    \n",
    "    \n",
    "    all_poi_images.append(np.array(poi_images))\n",
    "    all_sbp_values.append(np.array(combined_seg_sbp_batch.flatten()))\n",
    "    all_dbp_values.append(np.array(combined_seg_dbp_batch.flatten()))\n",
    "\n",
    "    print(f\"Batch {batch_idx + 1} processing complete.\")\n",
    "    \n",
    "\n",
    "all_poi_images = np.concatenate(all_poi_images, axis=0)\n",
    "all_sbp_values = np.concatenate(all_sbp_values, axis=0)\n",
    "all_dbp_values = np.concatenate(all_dbp_values, axis=0)     "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d3da8873-7769-4d2f-83fe-207108e6c20f",
   "metadata": {},
   "outputs": [],
   "source": [
    "y = np.column_stack((all_sbp_values, all_dbp_values))\n",
    "poi_images_normal = np.array(all_poi_images)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d82bbbd7-5d8a-4cb1-bb0d-2fef49676f93",
   "metadata": {},
   "outputs": [],
   "source": [
    "plot_poincare_matrix(poi_images_normal[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "709514c0-bcbd-410a-8aaa-389c9786f762",
   "metadata": {},
   "outputs": [],
   "source": [
    "len(poi_images_normal)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cc9be0c1-201d-4c19-82a5-4587fda1f4a5",
   "metadata": {},
   "outputs": [],
   "source": [
    "from keras.models import Sequential\n",
    "from keras.layers import Dense, Flatten, Dropout\n",
    "from keras.optimizers import Adam\n",
    "from keras.utils import to_categorical\n",
    "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
    "from sklearn.linear_model import Ridge\n",
    "\n",
    "\n",
    "batch_size = 32\n",
    "\n",
    "\n",
    "def image_generator(images, labels, batch_size):\n",
    "    num_samples = images.shape[0]\n",
    "    while True:\n",
    "        for offset in range(0, num_samples, batch_size):\n",
    "            batch_images = images[offset:offset+batch_size]\n",
    "            batch_labels = labels[offset:offset+batch_size]\n",
    "            batch_images_reshaped = batch_images.reshape(-1, 224, 224, 1)\n",
    "            batch_images_rgb = np.concatenate([batch_images_reshaped] * 3, axis=-1)\n",
    "            batch_images_preprocessed = preprocess_input(batch_images_rgb)\n",
    "            yield batch_images_preprocessed, batch_labels\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2f0fca4c-8498-48a2-9dd3-59aa63fd0c62",
   "metadata": {},
   "outputs": [],
   "source": [
    "from tensorflow.keras.applications import MobileNet\n",
    "from tensorflow.keras.layers import Flatten, Dense\n",
    "from tensorflow.keras.models import Model\n",
    "from tensorflow.keras.applications.mobilenet import preprocess_input\n",
    "\n",
    "\n",
    "base_model_mobile = MobileNet(weights='imagenet', include_top=False, input_shape=(224, 224, 3))\n",
    "\n",
    "\n",
    "for layer in base_model_mobile.layers:\n",
    "    layer.trainable = False\n",
    "\n",
    "\n",
    "x = base_model_mobile.output\n",
    "x = Flatten(name='flatten')(x)\n",
    "output = Dense(512, activation='linear', name='fc1')(x)\n",
    "\n",
    "\n",
    "# Define model\n",
    "model_mobile = Model(inputs=base_model_mobile.input, outputs=output)\n",
    "\n",
    "\n",
    "model_mobile.summary()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3f6fd068-6750-405e-bd96-230a504a31f3",
   "metadata": {},
   "outputs": [],
   "source": [
    "images = poi_images_normal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c7479743-8703-4c96-b4cd-28b5fb66a4e8",
   "metadata": {},
   "outputs": [],
   "source": [
    "labels = y\n",
    "num_samples = images.shape[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "605a5aa2-23bc-4af4-a37d-3672c745364f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define a new model to extract features from the 'fc1' layer of the trained model\n",
    "feature_extractor_mobile = Model(inputs=model_mobile.input, outputs=model_mobile.get_layer('fc1').output)\n",
    "\n",
    "# Function to extract features\n",
    "def extract_features(generator, num_samples):\n",
    "    features = []\n",
    "    for batch_images, _ in generator:\n",
    "        batch_features = feature_extractor_mobile.predict(batch_images)\n",
    "        features.append(batch_features)\n",
    "        if len(features) * batch_size >= num_samples:\n",
    "            break\n",
    "    return np.vstack(features)\n",
    "\n",
    "\n",
    "feature_generator_normal_1 = image_generator(images, np.zeros((num_samples,)), batch_size)\n",
    "\n",
    "\n",
    "features_normal_1 = extract_features(feature_generator_normal_1, num_samples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "109ac973-416c-449b-b1c8-2d775eb93f46",
   "metadata": {},
   "outputs": [],
   "source": [
    "features_normal_flattened_1= features_normal_1.reshape(features_normal_1.shape[0],-1)\n",
    "\n",
    "\n",
    "features_1= features_normal_flattened_1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b925bbf3-56bb-4a48-ade0-ae575a41c6fc",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "Mobile_train,Mobile_test,label_train,label_test=train_test_split(features_1,labels, test_size=0.2, random_state=42)\n",
    "ridge_model = Ridge(alpha=1.0)  \n",
    "ridge_model.fit(Mobile_train, label_train)\n",
    "\n",
    "\n",
    "predicted_mobile = ridge_model.predict(Mobile_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d768ab30-d81c-4807-88d2-0e230fbe7d44",
   "metadata": {},
   "outputs": [],
   "source": [
    "predicted_sbp =predicted_mobile[:, 0]  \n",
    "predicted_dbp =predicted_mobile[:, 1]  \n",
    "\n",
    "true_sbp = label_test[:, 0]  \n",
    "true_dbp = label_test[:, 1]  \n",
    "\n",
    "def calculate_metrics(predicted, true):\n",
    "    \n",
    "    R = np.corrcoef(predicted, true)[0, 1]\n",
    "\n",
    "   \n",
    "    MAE = np.mean(np.abs(predicted - true))\n",
    "\n",
    "   \n",
    "    RMSE = np.sqrt(np.mean((predicted - true) ** 2))\n",
    "\n",
    "    \n",
    "    ME = np.mean(predicted - true)\n",
    "    SD = np.std(predicted - true)\n",
    "\n",
    "    return R, MAE, RMSE, (ME, SD)\n",
    "\n",
    "\n",
    "sbp_metrics = calculate_metrics(predicted_sbp, true_sbp)\n",
    "print(f\"SBP Metrics: R={sbp_metrics[0]}, MAE={sbp_metrics[1]}, RMSE={sbp_metrics[2]}, ME±SD={sbp_metrics[3]}\")\n",
    "\n",
    "\n",
    "dbp_metrics = calculate_metrics(predicted_dbp, true_dbp)\n",
    "print(f\"DBP Metrics: R={dbp_metrics[0]}, MAE={dbp_metrics[1]}, RMSE={dbp_metrics[2]}, ME±SD={dbp_metrics[3]}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2b394e2d-8b18-4564-aec5-412d787f72e1",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "36ed7fe5-3862-437a-b235-6f106051936a",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.19"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
